////////////////////////////////////////////////////////////////////////////////
//
// Aranya Code
// author: TonyHack
// E-mail: tonyjobmails@gmail.com
//
// filename: url.cpp
// function: 成员函数的定义
//
////////////////////////////////////////////////////////////////////////////////

#include "url.h"

/////////////////////////////////////////////////////////////////////
/// 解析并返回协议类型 
uint32 URL::parse_scheme(const string& _scheme_s)
{
	/// 读取url配置类中的协议支持字段，根据配置文件的设置来决定支持协议的类型 
	//uint8 _scheme_bit = url_config::get_me()->get_support_type();

	uint8 _scheme_bit = 7;//////////////////此语句在配置文件模块完成后删除

	////////////////////////////////////////////////////////
	// 关于配置协议支持字段说明：
	// 此字段为8位，每一位代表一种协议，如下定义
	// 0位: HTTP | 1位: FTP | 2位: FILE | 3~7位: 暂无定义 
	////////////////////////////////////////////////////////
	if((_scheme_bit & 1) && (aranya_strnicmp(_scheme_s.c_str(), "http", 4) == 0))
	{
		return SCHEME_HTTP;
	}
	if((_scheme_bit & 2) && (aranya_strnicmp(_scheme_s.c_str(), "ftp", 3) == 0))
	{
		return SCHEME_FTP;
	}
	if((_scheme_bit & 4) && (aranya_strnicmp(_scheme_s.c_str(), "file", 4) == 0))
	{
		return SCHEME_FILE;
	}
	return SCHEME_OTHER;
	
}
/// 解析返回协议类型结束
//////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
/// 解析URL
/// 暂时使用只对HTTP协议的URL分析流程
bool URL::parse_url()
{
	if(this->url.empty()) return false;

	/// 标识协议
	const char double_bar[4] = "://";
	/// 标识其它
	const char branch[5] = {'@', ':', '/', '?'};
	/// url副本
	string carbon = url;	//carbon of url

	///////////////////////////////////////////////////
	/// 解析URL的协议部分
	string::size_type idx = carbon.find(double_bar); /// "://"
	if(idx != _END)	//找到"://", 有协议字段
	{
		string scheme_tmp = carbon.substr(_ZERO, idx);

		/// 去除协议字段
		carbon = carbon.substr(idx + 3);
		/// 解析出协议部分
		this->scheme = parse_scheme(scheme_tmp);
	}
	else	/// 默认为HTTP协议
		this->scheme = SCHEME_HTTP;
	/// 解析URL协议结束
	///////////////////////////////////////////////////
	uint32 pos = 0;
	///////////////////////////////////////////////////
	/// 解析URL用户名与密码部分
	if(carbon.empty())  return false;
	idx = carbon.find(branch[pos]);  /// "@"
	if(idx != _END)
	{
		string up_tmp = carbon.substr(_ZERO, idx);

		/// 去除用户名与密码字段
		carbon = carbon.substr(idx + 1);
		/// 分别解析用户名、密码两字段
		idx = up_tmp.find(branch[pos + 1]);  /// ":"
		if(idx != _END)  /// 用户名:密码
		{
			this->username = up_tmp.substr(_ZERO, idx);
			this->password = up_tmp.substr(idx + 1);
		}
		else  /// 没有";"，默认为用户名
			this->username = up_tmp;
	}
	/// 解析URL用户名与密码结束
	///////////////////////////////////////////////////

	///////////////////////////////////////////////////
	/// 解析URL主机与端口部分
	if(carbon.empty())  return false;
	idx = carbon.find(branch[pos + 2]);  /// "/"
	string hp_tmp("");
	if(idx != _END)
	{
		hp_tmp = carbon.substr(_ZERO, idx);
		/// 去除主机与端口字段
		carbon = carbon.substr(idx + 1);
	}
	else
	{
		hp_tmp = carbon;
		carbon = "";
	}
	/// 分别解析主机与端口两字段
	idx = hp_tmp.find(branch[pos + 1]);  /// ":"
	if(idx != _END)
	{
		this->host = hp_tmp.substr(_ZERO, idx);
		int32 tmp_port = atoi(hp_tmp.substr(idx + 1).c_str());
		if(tmp_port <= 0 || tmp_port > 65535)
			return false;
		this->port = tmp_port;

	}
	else
	{
		this->host = hp_tmp;
		/// 默认端口
		if(this->scheme == SCHEME_HTTP)
			this->port = 80;
		else if(this->scheme == SCHEME_FTP)
			this->port = 21;
		else  /// 其它协议暂时不做处理，端口设为初始值
			this->port = 0;
	}
	/// 解析URL主机与端口部分结束	
	///////////////////////////////////////////////////

	///////////////////////////////////////////////////
	/// 解析文件路径部分(路径和请求部分)
	if(carbon.empty())  return true;
	idx = carbon.find(branch[pos + 3]);  /// "?"
	if(idx != _END)
	{
		this->filename = carbon.substr(_ZERO, idx);
		this->search_part = carbon.substr(idx + 1);
	}
	else
		this->filename = carbon;
	/// 解析文件路径部分(路径和请求部分)结束
	///////////////////////////////////////////////////
	
	return true;
}
/// 解析URL结束
////////////////////////////////////////////////////////////////////////
